/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Estructuras;


/**
 *
 * @author Luis E Sosa S
 */
public class rt_sched_class extends sched_class{

//numero de prioridades
short tamano = 100;
public runqueue[] rq;




  public rt_sched_class() {
    rq = new runqueue[tamano];

  }


 /* funcion llamada cuando una tarea cambia a estado runnable
   * este coloca el scheduling_entity (proceso) dentro del scheduler_class
   */
   public  synchronized void   enqueue_task(Task_struct task){
     if(task == null)
       return;

     int pri = (int)task.getPrio();  
     boolean aux;
     //se verifica si se han creado la lista si no se ha creado se crea
     if(rq[pri]!=null){
         aux = rq[pri].enqueue_task(task);
         if(aux){
            impCreado(task);
         }
         else
           System.out.println("No pudo ser agregado pid="+ task.getPid());

     }
     else{//si no existe la cola la crea
         rq[pri] = new runqueue((short)pri);
         aux = rq[pri].enqueue_task(task);
         if(aux){
           impCreado(task);
         }
         else
           System.out.println("No pudo ser agregado pid="+ task.getPid());
     }
   }



   /**
    *Cuando una tarea no puede seguir ejecutandose esta funcion es llamada
    * para guardar el schedling_entity fuera del scheduler
    * esta decrementa la variable nr_running
    */
   public synchronized Task_struct dequeue_task(Task_struct ts){
   if(ts !=null){
      int pri = (int)ts.getPrio();
     if(rq[pri] != null){
       return rq[pri].dequeue_task(ts);
     }
     else
       return null;
   }
   return null;
}

  
 /**
  *Agrega un procesos a la cola de expirados
  *
  */
   public  void yield_task(Task_struct task){
     int pri = (int)task.getPrio();
     rq[pri].agregarExpirados(task);
 }



  /**
   * Agrega un proceso a la cola de expropiados
   */
   public void agregarExpropiado(Task_struct task){
      int pri = (int)task.getPrio();
      rq[pri].agregarEnExpropiados(task);
   }


    /**
   * Esta funcion revisa si una tarea en estado runnable con mayor prioridad
   * esta en el scheduler y de esta forma seleccionarla para que
   * se ejecute
   */
   public void check_preempt_curr(){
    //Recorrer la lista de task struct para ver si se agrego un
    //nuevo proceso con estado runnable
    //si es de mayor prioridad que la del proceso en ejecucion
   // se expropia el proceso

 }



//Variable estatica para guardar memoria de la lista procesada
  private static int memo = 0;
/**
  *Funcion que selecciona la tarea mas apropiada para ser ejecutada
  */
   public synchronized  Task_struct pick_next_task(){
   
     //ciclamos sobre la lista de prioridades
   Task_struct aux = null;
   //Numero de listas sin procesos si es 100 es porque no hay procesos
   int listasSinProcesos = 1;
   
   runqueue ruqu;
      //201 asegura 2 vueltas
      while( !((listasSinProcesos%201)== 0)){
         ruqu = rq[memo];
         //si no se ha creado la lista
         if(ruqu == null){
           memo = ((memo+1)%100);
           listasSinProcesos++;
           continue;
         }
          aux = ruqu.pick_next_task() ;
          //si no hay procesos se cambia de prioridad
          if( aux != null){
             return aux;
          }
          memo = ((memo+1)%100);
          listasSinProcesos++;
      }
   //System.out.println("No hay procesos por procesar en rt_sched");
   return null;
   }



  //funcion que imprime mensaje de creacion
   private void impCreado(Task_struct task){
    System.out.println("TS ingresado : pid="+ task.getPid() +
    "con prioridad="+ task.getPrio());

   }
 

 

}







